"""
任务相关的数据传输对象(DTO)定义
用于 API 请求和响应的数据模型
"""
from datetime import datetime
from typing import Optional, List, Dict, Union, Any
from pydantic import BaseModel, Field, field_validator
from app.models.base import PyObjectId
from app.models.task import TaskComment, TaskAttachment, TaskTimeLog

# ========== 评论相关 Schema ==========
class TaskCommentCreate(BaseModel):
    """创建任务评论模型"""
    content: str = Field(..., min_length=1, max_length=2000, description="评论内容")
    parent_comment_id: Optional[str] = Field(None, description="父评论ID，用于回复功能")

class TaskCommentUpdate(BaseModel):
    """更新任务评论模型"""
    content: Optional[str] = Field(None, min_length=1, max_length=2000, description="评论内容")
    status: Optional[str] = Field(None, description="评论状态（动态状态）")
    is_deleted: Optional[bool] = Field(None, description="是否删除（已废弃，使用status字段）")

# ========== 附件相关 Schema ==========
class TaskAttachmentCreate(BaseModel):
    """创建任务附件模型"""
    filename: str = Field(..., description="文件名")
    original_filename: str = Field(..., description="原始文件名")
    file_size: int = Field(..., description="文件大小")
    file_type: str = Field(..., description="文件类型")
    url: str = Field(..., description="文件URL")

# ========== 工时记录相关 Schema ==========
class TimeLogCreate(BaseModel):
    """创建工时记录模型"""
    hours: float = Field(..., gt=0, description="工时")
    description: Optional[str] = Field(None, max_length=500, description="工时描述")
    date: Optional[datetime] = Field(None, description="记录日期")

class TimeLogUpdate(BaseModel):
    """更新工时记录模型"""
    hours: Optional[float] = Field(None, gt=0, description="工时")
    description: Optional[str] = Field(None, max_length=500, description="工时描述")
    date: Optional[datetime] = Field(None, description="记录日期")

class TaskTimeLogCreate(BaseModel):
    """创建工时记录模型（完整版）"""
    hours: float = Field(..., ge=0, le=24, description="工时")
    description: Optional[str] = Field(None, max_length=500, description="工时描述")
    date: Optional[datetime] = Field(None, description="记录日期")

class TaskTimeLogUpdate(BaseModel):
    """更新工时记录模型（完整版）"""
    hours: Optional[float] = Field(None, ge=0, le=24, description="工时")
    description: Optional[str] = Field(None, max_length=500, description="工时描述")
    date: Optional[datetime] = Field(None, description="记录日期")

# ========== 创建和更新 Schema ==========
class TaskCreate(BaseModel):
    """创建任务模型"""
    title: str = Field(..., min_length=1, max_length=200, description="任务标题")
    description: Optional[str] = Field(None, max_length=5000, description="任务描述")
    task_type: str = Field(default="feature", description="任务类型")
    status: str = Field(default="", description="任务状态（从状态管理系统动态获取，创建时使用默认状态）")
    priority: str = Field(default="medium", description="任务优先级")
    project_id: PyObjectId = Field(..., description="所属项目ID")
    assignee_id: Optional[PyObjectId] = Field(None, description="负责人ID")
    reporter_id: PyObjectId = Field(..., description="报告人ID")
    parent_task_id: Optional[PyObjectId] = Field(None, description="父任务ID")
    estimated_hours: Optional[float] = Field(None, ge=0, description="预估工时")
    actual_hours: Optional[float] = Field(None, ge=0, description="实际工时")
    start_date: Optional[datetime] = Field(None, description="开始日期")
    due_date: Optional[datetime] = Field(None, description="截止日期")
    tags: List[str] = Field(default_factory=list, description="任务标签")
    
    @field_validator('start_date', 'due_date', mode='before')
    @classmethod
    def parse_date_fields(cls, v: Union[str, datetime, None]) -> Optional[datetime]:
        """将空字符串转换为 None，避免 Pydantic 验证错误"""
        if v == "" or v is None:
            return None
        if isinstance(v, str):
            # 如果是字符串，尝试解析
            try:
                return datetime.fromisoformat(v.replace('Z', '+00:00'))
            except (ValueError, AttributeError):
                return None
        return v

class TaskUpdate(BaseModel):
    """更新任务模型"""
    title: Optional[str] = Field(None, min_length=1, max_length=200, description="任务标题")
    description: Optional[str] = Field(None, max_length=5000, description="任务描述")
    task_type: Optional[str] = Field(None, description="任务类型")
    status: Optional[str] = Field(None, description="任务状态")
    priority: Optional[str] = Field(None, description="任务优先级")
    project_id: Optional[PyObjectId] = Field(None, description="所属项目ID")
    assignee_id: Optional[PyObjectId] = Field(None, description="负责人ID")
    reporter_id: Optional[PyObjectId] = Field(None, description="报告人ID")
    parent_task_id: Optional[PyObjectId] = Field(None, description="父任务ID")
    estimated_hours: Optional[float] = Field(None, ge=0, description="预估工时")
    actual_hours: Optional[float] = Field(None, ge=0, description="实际工时")
    progress: Optional[int] = Field(None, ge=0, le=100, description="任务进度（0-100）")
    start_date: Optional[datetime] = Field(None, description="开始日期")
    due_date: Optional[datetime] = Field(None, description="截止日期")
    tags: Optional[List[str]] = Field(None, description="任务标签")
    
    @field_validator('start_date', 'due_date', mode='before')
    @classmethod
    def parse_date_fields(cls, v: Union[str, datetime, None]) -> Optional[datetime]:
        """将空字符串转换为 None，避免 Pydantic 验证错误"""
        if v == "" or v is None:
            return None
        if isinstance(v, str):
            # 如果是字符串，尝试解析
            try:
                return datetime.fromisoformat(v.replace('Z', '+00:00'))
            except (ValueError, AttributeError):
                return None
        return v

# ========== 操作相关 Schema ==========
class TaskStatusUpdate(BaseModel):
    """任务状态更新模型"""
    status: str = Field(..., description="新状态")
    comment: Optional[str] = Field(None, max_length=500, description="状态变更说明")

class TaskAssigneeUpdate(BaseModel):
    """任务负责人更新模型"""
    assignee_id: Optional[str] = Field(None, description="负责人ID")
    comment: Optional[str] = Field(None, max_length=500, description="分配说明")

class TaskAssignmentUpdate(BaseModel):
    """任务分配更新模型（别名）"""
    assignee_id: Optional[str] = Field(None, description="负责人ID")
    comment: Optional[str] = Field(None, max_length=500, description="分配说明")

class TaskBulkUpdate(BaseModel):
    """批量更新任务模型"""
    task_ids: List[str] = Field(..., min_length=1, description="任务ID列表")
    updates: TaskUpdate = Field(..., description="更新内容")

# ========== 响应 Schema ==========
class TaskResponse(BaseModel):
    """任务响应模型"""
    id: str = Field(..., description="任务ID")
    title: str = Field(..., description="任务标题")
    description: Optional[str] = Field(None, description="任务描述")
    task_type: str = Field(..., description="任务类型")
    status: str = Field(..., description="任务状态")
    priority: str = Field(..., description="任务优先级")
    project_id: str = Field(..., description="所属项目ID")
    project_name: Optional[str] = Field(None, description="项目名称")
    assignee_id: Optional[str] = Field(None, description="负责人ID")
    assignee_name: Optional[str] = Field(None, description="负责人姓名")
    assignee_avatar: Optional[str] = Field(None, description="负责人头像")
    reporter_id: str = Field(..., description="报告人ID")
    reporter_name: Optional[str] = Field(None, description="报告人姓名")
    created_by: Optional[str] = Field(None, description="创建人ID")
    creator_name: Optional[str] = Field(None, description="创建人姓名")
    creator_avatar: Optional[str] = Field(None, description="创建人头像")
    parent_task_id: Optional[str] = Field(None, description="父任务ID")
    parent_task_title: Optional[str] = Field(None, description="父任务标题")
    estimated_hours: Optional[float] = Field(None, description="预估工时")
    actual_hours: Optional[float] = Field(None, description="实际工时")
    start_date: Optional[datetime] = Field(None, description="开始日期")
    due_date: Optional[datetime] = Field(None, description="截止日期")
    tags: List[str] = Field(default_factory=list, description="任务标签")
    comments: List[TaskComment] = Field(default_factory=list, description="任务评论")
    attachments: List[TaskAttachment] = Field(default_factory=list, description="任务附件")
    time_logs: List[TaskTimeLog] = Field(default_factory=list, description="工时记录")
    watchers: List[str] = Field(default_factory=list, description="关注者ID列表")
    created_at: datetime = Field(..., description="创建时间")
    updated_at: datetime = Field(..., description="更新时间")
    completed_at: Optional[datetime] = Field(None, description="完成时间")
    
    # 计算字段
    is_overdue: Optional[bool] = Field(None, description="是否逾期")
    progress: Optional[float] = Field(None, description="任务进度百分比")
    subtask_count: Optional[int] = Field(None, description="子任务数量")
    completed_subtask_count: Optional[int] = Field(None, description="已完成子任务数量")
    comment_count: Optional[int] = Field(None, description="评论数量")
    attachment_count: Optional[int] = Field(None, description="附件数量")
    total_time_spent: Optional[float] = Field(None, description="总工时")
    version_id: Optional[str] = Field(None, description="版本ID")
    version_name: Optional[str] = Field(None, description="版本名称")
    version_number: Optional[str] = Field(None, description="版本号")

class TaskSummary(BaseModel):
    """任务摘要模型"""
    id: str = Field(..., description="任务ID")
    title: str = Field(..., description="任务标题")
    status: str = Field(..., description="任务状态")
    priority: str = Field(..., description="任务优先级")
    assignee_name: Optional[str] = Field(None, description="负责人姓名")
    due_date: Optional[datetime] = Field(None, description="截止日期")
    is_overdue: bool = Field(..., description="是否逾期")
    progress: float = Field(..., description="任务进度百分比")

class TaskBoard(BaseModel):
    """任务看板模型"""
    project_id: str = Field(..., description="项目ID")
    project_name: str = Field(..., description="项目名称")
    columns: Dict[str, List[TaskSummary]] = Field(..., description="看板列")

class TaskBoardColumn(BaseModel):
    """任务看板列模型"""
    status: str = Field(..., description="状态")
    title: str = Field(..., description="列标题")
    tasks: List[TaskSummary] = Field(default_factory=list, description="任务列表")
    task_count: int = Field(..., description="任务数量")

# ========== 筛选和统计 Schema ==========
class TaskFilter(BaseModel):
    """任务筛选模型"""
    project_id: Optional[PyObjectId] = Field(None, description="项目ID")
    task_type: Optional[str] = Field(None, description="任务类型")
    status: Optional[str] = Field(None, description="任务状态")
    priority: Optional[str] = Field(None, description="任务优先级")
    assignee_id: Optional[PyObjectId] = Field(None, description="负责人ID")
    reporter_id: Optional[PyObjectId] = Field(None, description="报告人ID")
    start_date_from: Optional[datetime] = Field(None, description="开始日期从")
    start_date_to: Optional[datetime] = Field(None, description="开始日期到")
    due_date_from: Optional[datetime] = Field(None, description="截止日期从")
    due_date_to: Optional[datetime] = Field(None, description="截止日期到")
    tags: Optional[List[str]] = Field(None, description="任务标签")
    search: Optional[str] = Field(None, description="搜索关键词")
    page: int = Field(default=1, ge=1, description="页码")
    page_size: int = Field(default=20, ge=1, le=100, description="每页数量")

class TaskStats(BaseModel):
    """任务统计模型"""
    total_tasks: int = Field(..., description="任务总数")
    completed_tasks: int = Field(..., description="已完成任务数")
    in_progress_tasks: int = Field(..., description="进行中任务数")
    overdue_tasks: int = Field(..., description="逾期任务数")
    tasks_by_status: Dict[str, int] = Field(..., description="按状态分组的任务数")
    tasks_by_priority: Dict[str, int] = Field(..., description="按优先级分组的任务数")
    tasks_by_type: Dict[str, int] = Field(..., description="按类型分组的任务数")
    tasks_by_assignee: Dict[str, int] = Field(..., description="按负责人分组的任务数")

class TaskStatistics(BaseModel):
    """任务统计模型（详细版）"""
    total_count: int = Field(..., description="总任务数")
    completed_count: int = Field(..., description="已完成任务数")
    in_progress_count: int = Field(..., description="进行中任务数")
    todo_count: int = Field(..., description="待办任务数")
    overdue_count: int = Field(..., description="逾期任务数")
    by_priority: Dict[str, int] = Field(..., description="按优先级统计")
    by_type: Dict[str, int] = Field(..., description="按类型统计")
    by_status: Dict[str, int] = Field(..., description="按状态统计")

# ========== 活动相关 Schema ==========
class TaskActivity(BaseModel):
    """任务活动模型"""
    id: str = Field(..., description="活动ID")
    task_id: str = Field(..., description="任务ID")
    user_id: str = Field(..., description="用户ID")
    user_name: str = Field(..., description="用户名称")
    action: str = Field(..., description="操作类型")
    description: str = Field(..., description="操作描述")
    old_value: Optional[str] = Field(None, description="旧值")
    new_value: Optional[str] = Field(None, description="新值")
    metadata: Dict[str, Any] = Field(default_factory=dict, description="元数据")
    created_at: datetime = Field(..., description="创建时间")
